package com.cn.sys.frame.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cn.sys.common.Constants;
import com.cn.sys.frame.util.SpringContextUtil;
import com.cn.sys.main.entity.SysFunction;
import com.cn.sys.main.entity.SysModule;
import com.cn.sys.main.entity.SysUser;
import com.cn.sys.main.service.SysFunctionService;

public class UserRequestFilter implements Filter {

	private static final Logger logger = LoggerFactory.getLogger(UserRequestFilter.class);
	private static List<SysFunction> publicFunctions = null;
	
	public void destroy() {
		logger.info("destroy!!!");
	}

	// 执行过滤
	@SuppressWarnings("unchecked")
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		if (request != null) {
			HttpServletRequest httpRequest = (HttpServletRequest) request;
			HttpServletResponse httpResponse = (HttpServletResponse)response;
			logger.info("请求的url:"+httpRequest.getRequestURI());
			if(!isPublicUrl(httpRequest)){
				SysUser loginUser = (SysUser) httpRequest.getSession().getAttribute(Constants.USER_CONTEXT);
				if(loginUser==null || StringUtils.isBlank(loginUser.getUserName())){
					// 如果是ajax请求响应头会有，x-requested-with；
					if (httpRequest.getHeader("x-requested-with") != null && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
						httpResponse.setStatus(911);  //表示session timeout
		            }else {
		            	httpResponse.sendRedirect(httpRequest.getContextPath()+"/errorPages/sessionOut.jsp");
					}
					return ;
				}
				String requestUrl = httpRequest.getRequestURI();
				boolean result = false;
				if(StringUtils.contains(requestUrl, "validate")){//带有validate字符串的请求不进行权限验证
					result = true;
				}
				if(!result){
					HttpSession session = httpRequest.getSession();
					String contextPath = httpRequest.getContextPath()+"/";
					List<SysModule> moduleList = (List<SysModule>) session.getAttribute(Constants.USER_MODULES);
					List<SysFunction> funcList = (List<SysFunction>) session.getAttribute(Constants.USER_FUNCTIONS);
					
					for (SysModule module : moduleList) {
						if((contextPath+module.getUrl()).equals(requestUrl)){
							result = true;
							break;
						}
					}
					if(!result){
						for (SysFunction func : funcList) {
							if((contextPath+func.getUrl()).equals(requestUrl)){
								result = true;
								break;
							}
						}
					}
				}
				
				if(!result){
					// 如果是ajax请求响应头会有，x-requested-with；
					if (httpRequest.getHeader("x-requested-with") != null && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
						httpResponse.setStatus(912);  //表示无权限操作
						logger.info("无权请求的url:"+requestUrl);
		            }else {
					    httpResponse.sendRedirect(httpRequest.getContextPath()+"/errorPages/404.jsp");
		            }
					return ;
				}
			}
			chain.doFilter(request, response);
		}
	}

	private boolean isPublicUrl(HttpServletRequest request) {
		String requestUrl = request.getRequestURI();
		String contextPath = request.getContextPath()+"/";
		if ((contextPath+"toLogin.do").equalsIgnoreCase(requestUrl) 
			|| (contextPath+"login.do").equalsIgnoreCase(requestUrl)
			|| (contextPath+"doLogout.do").equalsIgnoreCase(requestUrl)) {
			return true;
		}
		if(publicFunctions==null||publicFunctions.isEmpty()){
			SysFunctionService functionService = SpringContextUtil.getBean("sysFunctionService");
			try {
				publicFunctions = functionService.getPublicFunctions();
			} catch (Exception e) {
				//e.printStackTrace();
				logger.error("获取公用请求出错 : ["+e.getMessage()+"]");
			}
		}
		boolean result = false;
		for (SysFunction func : publicFunctions) {
			if((contextPath+func.getUrl()).equals(requestUrl)){
				result = true;
				break;
			}
		}
		return result;
	}

	public void init(FilterConfig arg0) throws ServletException {
		logger.info("UserRequestFilter init........");
	}

}
